﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Mime;
using System.Text;
using System.Threading.Tasks;
using ComputerArchitecture.Core;
using ComputerArchitecture.Numbers;
using ComputerArchitecture.Units.Interfaces;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;

namespace ComputerArchitecture.Lab2
{
    internal class Program
    {
        #region Fields

        private readonly static IUnityContainer UnitsContainer = new UnityContainer().LoadConfiguration("units");

        #endregion

        static int Main(string[] args)
        {
            Console.WriteLine("Aleksey Suharev Multiply bit number emulator @ 2013 p4s group");
            int size = -1;
            Func<string, ISignedBitNumber> createBitNumber = null;
            Func<ISignedBitNumber, string> getNormal = null;
            do
            {
                try
                {
                    Console.Write("Enter the size of operands: ");
                    string sizeString = Console.ReadLine();
                    if (ReferenceEquals(sizeString, null))
                    {
                        throw new ArgumentNullException("sizeString");
                    }
                    size = int.Parse(sizeString);
                    switch (size)
                    {
                        case 8:
                            createBitNumber = s => sbyte.Parse(s).CreateByteNumber();
                            getNormal = b => b.ToInt16().ToString();
                            break;
                        case 16:
                            createBitNumber = s => short.Parse(s).CreateWordNumber();
                            getNormal = b => b.ToInt32().ToString();
                            break;
                        case 32:
                            createBitNumber = s => int.Parse(s).CreateDoubleWordNumber();
                            getNormal = b => b.ToInt64().ToString();
                            break;
                        default:
                            throw new ArgumentException();
                    }
                }
                catch (FormatException)
                {
                    Console.WriteLine("Incorrect input! Try again.");
                    size = -1;
                }
                catch (ArgumentNullException)
                {
                    Console.WriteLine("Incorrect input! Try again.");
                    size = -1;
                }
                catch (ArgumentException)
                {
                    Console.WriteLine("Only 8, 16, 32 bits number supported!");
                    size = -1;
                }
                catch (Exception)
                {
                    Console.WriteLine("oops, something wrong!");
                    return -1;
                }
            } while (size == -1);
            if (ReferenceEquals(createBitNumber, null))
            {
                throw new ArgumentNullException("func");
            }
            if (ReferenceEquals(getNormal, null))
            {
                throw new ArgumentNullException("getNormal");
            }

            Console.Write("Enter first number: ");
            string firstNumberString = Console.ReadLine();
            ISignedBitNumber first = createBitNumber(firstNumberString);
            Console.Write("Enter second number: ");
            string secondNumberString = Console.ReadLine();
            ISignedBitNumber second = createBitNumber(secondNumberString);
            IMultiplyUnit multiplyUnit = UnitsContainer.Resolve<IMultiplyUnit>();
            ISignedBitNumber result = multiplyUnit.Multiply(first, second);
            Console.WriteLine("RESULT: {0} ({1})", result, getNormal(result));
            return 0;
        }
    }
}
